package com.hdu.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hdu.entity.Exam;
import com.hdu.mapper.ExamMapper;
import com.hdu.pojo.*;
import com.hdu.service.IExamService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import javafx.scene.chart.Chart;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 * 考试实体类 服务实现类
 * </p>
 *
 * @author xiaobai
 * @since 2025-02-06
 */
@Service
@RequiredArgsConstructor
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IExamService {

    private final ExamMapper examMapper;
    private final String[] course = new String[]{"chinese", "math", "english", "physical", "chemistry", "biology", "history", "political", "geography", "arts", "tech", "science", "liberal", "total"};
    private final String[] name = new String[]{"语文", "数学", "英语", "物理", "化学", "生物", "历史", "政治", "地理", "文综", "理综", "理科", "文科", "总分"};
    private final Integer[] score = new Integer[]{150, 150, 150, 100, 100, 100, 100, 100, 100, 300, 300, 750, 750, 1050};


    @Override
    public List<Exam> listExam(String grade, String label, String start, String end, String name) {
        return examMapper.list(grade, label, start, end, name);
    }

    @Override
    public Exam detailExam(String id) {
        return examMapper.getExam(id);
    }

    /**
     * 获取总体考试成绩信息
     */
    @Override
    public PageBean<Score> page(Integer page, Integer pageSize, String id, String name, String prop, String order, String cID, String mID) {

        //1. 设置分页参数
        PageHelper.startPage(page, pageSize);

        List<Score> scoreList = examMapper.wholeGrade(id, name, prop, order, cID, mID);

        Page<Score> p = (Page<Score>) scoreList;

        //3. 封装PageBean对象
        return new PageBean<>(p.getTotal(), p.getResult());
    }

    /**
     * 获取参考班级班级信息
     */
    @Override
    public List<String> listClass(String id) {
        return examMapper.listClass(id.substring(0, 2));
    }

    /**
     * 获取参考班级考试成绩信息
     */
    @Override
    public List<Rank> classGrade(String sID, String cID, String mID, String subject) {
        String eID = examMapper.getExamID(examMapper.examRank(mID));
        if (eID == null) {
            eID = mID;
        }
        return examMapper.classGrade(sID, cID, mID, eID, subject);
    }

    @Override
    public List<List<Rank>> requireFollow(String cID, String mID, String subject) {
        List<List<Rank>> requireFollow = new ArrayList<>();
        List<Rank> rankList = classGrade("", cID, mID, subject);
        System.out.println(rankList);
        List<Rank> ranks = new ArrayList<>();
        rankList.sort((o1, o2) -> o2.getProgressGRank() - o1.getProgressGRank());
        for (int i = 0; i < 10; i++) {
            if (rankList.get(i).getProgressGRank() >= 0) {
                ranks.add(rankList.get(i));
            }
        }
        requireFollow.add(new ArrayList<>(ranks));
        ranks.clear();
        rankList.sort(Comparator.comparingInt(Rank::getProgressGRank));
        for (int i = 0; i < 10; i++) {
            if (rankList.get(i).getProgressGRank() <= 0) {
                ranks.add(rankList.get(i));
            }
        }
        requireFollow.add(new ArrayList<>(ranks));
        ranks.clear();
        for (Rank rank : rankList) {
            if (rank.getScore() >= score[Arrays.asList(course).indexOf(subject)] * 0.55 && rank.getScore() <= score[Arrays.asList(course).indexOf(subject)] * 0.65) {
                ranks.add(rank);
            }
        }
        requireFollow.add(new ArrayList<>(ranks));
        ranks.clear();
        rankList.sort((o1, o2) -> Math.abs(o2.getProgressGRank()) - Math.abs(o1.getProgressGRank()));
        for (int i = 0; i < 10; i++) {
            ranks.add(rankList.get(i));
        }
        requireFollow.add(new ArrayList<>(ranks));
        return requireFollow;
    }

    @Override
    public List<Rank> containGrade(String sID, String cID, String mID, String[] subject) {
        List<Rank> rankList = new ArrayList<>();
        for (String str : subject) {
            List<Rank> ranks = classGrade(sID, cID, mID, str);
            for (Rank rank : ranks) {
                rank.setSubject(str);
                rankList.add(rank);
            }
        }
        return rankList;
    }

    @Override
    public List<Table> classTable(String cID, String mID, String subject) {
        if (subject.equals("all")) {
            List<Table> classTable = new ArrayList<>();
            for (int i = 0; i < course.length; i++) {
                classTable.addAll(examMapper.examTable(cID, mID, course[i], name[i], score[i]));
            }
            return classTable;
        } else {
            int num = Arrays.asList(course).indexOf(subject);
            return examMapper.examTable(cID, mID, subject, name[num], score[num]);
        }
    }

    @Override
    public List<Table> subjectTable(String subject, String mID) {
        int num = Arrays.asList(course).indexOf(subject);
        return examMapper.examTable("", mID, subject, name[num], score[num]);
    }

    @Override
    public List<String[]> averageGrade(String cID, String mID) {
        List<String[]> averageGrade = new ArrayList<>();
        String eID = examMapper.getExamID(examMapper.examRank(mID));
        if (eID == null) {
            eID = mID;
        }
        averageGrade.add(examMapper.averageGrade("", mID).toString().split(","));
        averageGrade.add(examMapper.averageGrade(cID, mID).toString().split(","));
        averageGrade.add(examMapper.averageGrade(cID, eID).toString().split(","));
        return averageGrade;
    }

    @Override
    public Double[] gradeScore(String mID, String subject) {
        return new Double[]{examMapper.avgScore(mID, subject), examMapper.topScore(mID, subject)};
    }

    @Override
    public List<DataCell> listHistogram(String subject, String cID, String mID) {
        List<Rank> rankList = examMapper.listLabel(subject, cID, mID);
        List<DataCell> charts = new ArrayList<>();
        int[] num = new int[35];
        for (Rank rank : rankList) {
            int location;
            if (Arrays.asList(new String[]{"chinese", "math", "english"}).contains(subject)) {
                location = rank.getScore() == 150 ? 14 : rank.getScore() / 10;
            } else if (Arrays.asList(new String[]{"arts", "tech"}).contains(subject)) {
                location = rank.getScore() == 300 ? 14 : rank.getScore() / 10;
            } else if (Arrays.asList(new String[]{"science", "liberal"}).contains(subject)) {
                location = rank.getScore() == 750 ? 24 : rank.getScore() / 30;
            } else if (subject.equals("total")) {
                location = rank.getScore() == 1050 ? 34 : rank.getScore() / 30;
            } else {
                location = rank.getScore() == 100 ? 9 : rank.getScore() / 10;
            }
            num[location]++;
        }
        int min = 0;
        int max = 35;
        while (num[max - 1] == 0) {
            max--;
        }
        while (num[min] == 0) {
            min++;
        }
        for (; min < max; min++) {
            if (Arrays.asList(new String[]{"science", "liberal", "total"}).contains(subject)) {
                charts.add(DataCell.of(String.valueOf(min * 30 + 15), (double) num[min]));
            } else {
                charts.add(DataCell.of(String.valueOf(min * 10 + 5), (double) num[min]));
            }

        }
        return charts;
    }

    @Override
    public List<Rank> listLabel(String subject, String cID, String mID, String score) {
        List<Rank> lists = examMapper.listLabel(subject, cID, mID);
        List<Rank> ranks = new ArrayList<>();
        int start, end;
        if (Arrays.asList(new String[]{"chinese", "math", "english"}).contains(subject)) {
            start = 5;
            end = 150;
        } else if (Arrays.asList(new String[]{"arts", "tech"}).contains(subject)) {
            start = 5;
            end = 300;
        } else if (Arrays.asList(new String[]{"science", "liberal"}).contains(subject)) {
            start = 15;
            end = 750;
        } else if (subject.equals("total")) {
            start = 15;
            end = 1050;
        } else {
            start = 5;
            end = 100;
        }
        for (Rank rank : lists) {
            int min = Integer.parseInt(score) - start - 1;
            int max = Integer.parseInt(score) == end - start ? end + 1 : Integer.parseInt(score) + start;
            if (rank.getScore() > min && rank.getScore() < max) {
                ranks.add(rank);
            }
        }
        return ranks;
    }
}
